summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/audio_in_manager.cpp7
-rw-r--r--src/audio_core/audio_in_manager.h4
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/hle/service/audio/audin_u.cpp198
-rw-r--r--src/core/hle/service/audio/audin_u.h38
-rw-r--r--src/core/hle/service/audio/audio.cpp4
-rw-r--r--src/core/hle/service/audio/audio_in_manager.cpp126
-rw-r--r--src/core/hle/service/audio/audio_in_manager.h57
8 files changed, 191 insertions, 247 deletions
diff --git a/src/audio_core/audio_in_manager.cpp b/src/audio_core/audio_in_manager.cpp
index a3667524f..63b064922 100644
--- a/src/audio_core/audio_in_manager.cpp
+++ b/src/audio_core/audio_in_manager.cpp
@@ -73,16 +73,15 @@ void Manager::BufferReleaseAndRegister() {
}
}
-u32 Manager::GetDeviceNames(std::vector<Renderer::AudioDevice::AudioDeviceName>& names,
- [[maybe_unused]] const u32 max_count,
+u32 Manager::GetDeviceNames(std::span<Renderer::AudioDevice::AudioDeviceName> names,
[[maybe_unused]] const bool filter) {
std::scoped_lock l{mutex};
LinkToManager();
auto input_devices{Sink::GetDeviceListForSink(Settings::values.sink_id.GetValue(), true)};
- if (input_devices.size() > 1) {
- names.emplace_back("Uac");
+ if (!input_devices.empty() && !names.empty()) {
+ names[0] = Renderer::AudioDevice::AudioDeviceName("Uac");
return 1;
}
return 0;
diff --git a/src/audio_core/audio_in_manager.h b/src/audio_core/audio_in_manager.h
index 5c4614cd1..2179990e0 100644
--- a/src/audio_core/audio_in_manager.h
+++ b/src/audio_core/audio_in_manager.h
@@ -60,13 +60,11 @@ public:
* Get a list of audio in device names.
*
* @param names - Output container to write names to.
- * @param max_count - Maximum number of device names to write. Unused
* @param filter - Should the list be filtered? Unused.
*
* @return Number of names written.
*/
- u32 GetDeviceNames(std::vector<Renderer::AudioDevice::AudioDeviceName>& names, u32 max_count,
- bool filter);
+ u32 GetDeviceNames(std::span<Renderer::AudioDevice::AudioDeviceName> names, bool filter);
/// Core system
Core::System& system;
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 75a9bcde7..51fe8c500 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -489,8 +489,8 @@ add_library(core STATIC
hle/service/apm/apm_controller.h
hle/service/apm/apm_interface.cpp
hle/service/apm/apm_interface.h
- hle/service/audio/audin_u.cpp
- hle/service/audio/audin_u.h
+ hle/service/audio/audio_in_manager.cpp
+ hle/service/audio/audio_in_manager.h
hle/service/audio/audio_in.cpp
hle/service/audio/audio_in.h
hle/service/audio/audio.cpp
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
deleted file mode 100644
index 0937d6d12..000000000
--- a/src/core/hle/service/audio/audin_u.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/string_util.h"
-#include "core/hle/service/audio/audin_u.h"
-#include "core/hle/service/audio/audio_in.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::Audio {
-using namespace AudioCore::AudioIn;
-
-AudInU::AudInU(Core::System& system_)
- : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"},
- impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, &AudInU::ListAudioIns, "ListAudioIns"},
- {1, &AudInU::OpenAudioIn, "OpenAudioIn"},
- {2, &AudInU::ListAudioIns, "ListAudioInsAuto"},
- {3, &AudInU::OpenAudioIn, "OpenAudioInAuto"},
- {4, &AudInU::ListAudioInsAutoFiltered, "ListAudioInsAutoFiltered"},
- {5, &AudInU::OpenAudioInProtocolSpecified, "OpenAudioInProtocolSpecified"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
-}
-
-AudInU::~AudInU() = default;
-
-void AudInU::ListAudioIns(HLERequestContext& ctx) {
- using namespace AudioCore::Renderer;
-
- LOG_DEBUG(Service_Audio, "called");
-
- const auto write_count =
- static_cast<u32>(ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>());
- std::vector<AudioDevice::AudioDeviceName> device_names{};
-
- u32 out_count{0};
- if (write_count > 0) {
- out_count = impl->GetDeviceNames(device_names, write_count, false);
- ctx.WriteBuffer(device_names);
- }
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(out_count);
-}
-
-void AudInU::ListAudioInsAutoFiltered(HLERequestContext& ctx) {
- using namespace AudioCore::Renderer;
-
- LOG_DEBUG(Service_Audio, "called");
-
- const auto write_count =
- static_cast<u32>(ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>());
- std::vector<AudioDevice::AudioDeviceName> device_names{};
-
- u32 out_count{0};
- if (write_count > 0) {
- out_count = impl->GetDeviceNames(device_names, write_count, true);
- ctx.WriteBuffer(device_names);
- }
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(out_count);
-}
-
-void AudInU::OpenAudioIn(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- auto in_params{rp.PopRaw<AudioInParameter>()};
- auto applet_resource_user_id{rp.PopRaw<u64>()};
- const auto device_name_data{ctx.ReadBuffer()};
- auto device_name = Common::StringFromBuffer(device_name_data);
- auto handle{ctx.GetCopyHandle(0)};
-
- auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)};
- if (process.IsNull()) {
- LOG_ERROR(Service_Audio, "Failed to get process handle");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultUnknown);
- return;
- }
-
- std::scoped_lock l{impl->mutex};
- auto link{impl->LinkToManager()};
- if (link.IsError()) {
- LOG_ERROR(Service_Audio, "Failed to link Audio In to Audio Manager");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(link);
- return;
- }
-
- size_t new_session_id{};
- auto result{impl->AcquireSessionId(new_session_id)};
- if (result.IsError()) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id,
- impl->num_free_sessions);
-
- auto audio_in =
- std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, in_params,
- process.GetPointerUnsafe(), applet_resource_user_id);
- impl->sessions[new_session_id] = audio_in->GetImpl();
- impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id;
-
- auto& out_system = impl->sessions[new_session_id]->GetSystem();
- AudioInParameterInternal out_params{.sample_rate = out_system.GetSampleRate(),
- .channel_count = out_system.GetChannelCount(),
- .sample_format =
- static_cast<u32>(out_system.GetSampleFormat()),
- .state = static_cast<u32>(out_system.GetState())};
-
- IPC::ResponseBuilder rb{ctx, 6, 0, 1};
-
- std::string out_name{out_system.GetName()};
- ctx.WriteBuffer(out_name);
-
- rb.Push(ResultSuccess);
- rb.PushRaw<AudioInParameterInternal>(out_params);
- rb.PushIpcInterface<IAudioIn>(audio_in);
-}
-
-void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- auto protocol_specified{rp.PopRaw<u64>()};
- auto in_params{rp.PopRaw<AudioInParameter>()};
- auto applet_resource_user_id{rp.PopRaw<u64>()};
- const auto device_name_data{ctx.ReadBuffer()};
- auto device_name = Common::StringFromBuffer(device_name_data);
- auto handle{ctx.GetCopyHandle(0)};
-
- auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)};
- if (process.IsNull()) {
- LOG_ERROR(Service_Audio, "Failed to get process handle");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultUnknown);
- return;
- }
-
- std::scoped_lock l{impl->mutex};
- auto link{impl->LinkToManager()};
- if (link.IsError()) {
- LOG_ERROR(Service_Audio, "Failed to link Audio In to Audio Manager");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(link);
- return;
- }
-
- size_t new_session_id{};
- auto result{impl->AcquireSessionId(new_session_id)};
- if (result.IsError()) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id,
- impl->num_free_sessions);
-
- auto audio_in =
- std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, in_params,
- process.GetPointerUnsafe(), applet_resource_user_id);
- impl->sessions[new_session_id] = audio_in->GetImpl();
- impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id;
-
- auto& out_system = impl->sessions[new_session_id]->GetSystem();
- AudioInParameterInternal out_params{.sample_rate = out_system.GetSampleRate(),
- .channel_count = out_system.GetChannelCount(),
- .sample_format =
- static_cast<u32>(out_system.GetSampleFormat()),
- .state = static_cast<u32>(out_system.GetState())};
-
- IPC::ResponseBuilder rb{ctx, 6, 0, 1};
-
- std::string out_name{out_system.GetName()};
- if (protocol_specified == 0) {
- if (out_system.IsUac()) {
- out_name = "UacIn";
- } else {
- out_name = "DeviceIn";
- }
- }
-
- ctx.WriteBuffer(out_name);
-
- rb.Push(ResultSuccess);
- rb.PushRaw<AudioInParameterInternal>(out_params);
- rb.PushIpcInterface<IAudioIn>(audio_in);
-}
-
-} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audin_u.h b/src/core/hle/service/audio/audin_u.h
deleted file mode 100644
index 51e770ff9..000000000
--- a/src/core/hle/service/audio/audin_u.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "audio_core/audio_in_manager.h"
-#include "audio_core/in/audio_in.h"
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/service.h"
-
-namespace Core {
-class System;
-}
-
-namespace AudioCore::AudioOut {
-class Manager;
-class In;
-} // namespace AudioCore::AudioOut
-
-namespace Service::Audio {
-
-class AudInU final : public ServiceFramework<AudInU> {
-public:
- explicit AudInU(Core::System& system_);
- ~AudInU() override;
-
-private:
- void ListAudioIns(HLERequestContext& ctx);
- void ListAudioInsAutoFiltered(HLERequestContext& ctx);
- void OpenInOutImpl(HLERequestContext& ctx);
- void OpenAudioIn(HLERequestContext& ctx);
- void OpenAudioInProtocolSpecified(HLERequestContext& ctx);
-
- KernelHelpers::ServiceContext service_context;
- std::unique_ptr<AudioCore::AudioIn::Manager> impl;
-};
-
-} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp
index 44af030eb..7dcfbbfad 100644
--- a/src/core/hle/service/audio/audio.cpp
+++ b/src/core/hle/service/audio/audio.cpp
@@ -2,9 +2,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
-#include "core/hle/service/audio/audin_u.h"
#include "core/hle/service/audio/audio.h"
#include "core/hle/service/audio/audio_controller.h"
+#include "core/hle/service/audio/audio_in_manager.h"
#include "core/hle/service/audio/audout_u.h"
#include "core/hle/service/audio/audrec_a.h"
#include "core/hle/service/audio/audrec_u.h"
@@ -19,8 +19,8 @@ void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system));
+ server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system));
server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system));
- server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(system));
server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system));
server_manager->RegisterNamedService("audrec:u", std::make_shared<AudRecU>(system));
server_manager->RegisterNamedService("audren:u", std::make_shared<AudRenU>(system));
diff --git a/src/core/hle/service/audio/audio_in_manager.cpp b/src/core/hle/service/audio/audio_in_manager.cpp
new file mode 100644
index 000000000..0379a2f68
--- /dev/null
+++ b/src/core/hle/service/audio/audio_in_manager.cpp
@@ -0,0 +1,126 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/string_util.h"
+#include "core/hle/service/audio/audio_in.h"
+#include "core/hle/service/audio/audio_in_manager.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::Audio {
+using namespace AudioCore::AudioIn;
+
+IAudioInManager::IAudioInManager(Core::System& system_)
+ : ServiceFramework{system_, "audin:u"},
+ impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, C<&IAudioInManager::ListAudioIns>, "ListAudioIns"},
+ {1, C<&IAudioInManager::OpenAudioIn>, "OpenAudioIn"},
+ {2, C<&IAudioInManager::ListAudioIns>, "ListAudioInsAuto"},
+ {3, C<&IAudioInManager::OpenAudioIn>, "OpenAudioInAuto"},
+ {4, C<&IAudioInManager::ListAudioInsAutoFiltered>, "ListAudioInsAutoFiltered"},
+ {5, C<&IAudioInManager::OpenAudioInProtocolSpecified>, "OpenAudioInProtocolSpecified"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+IAudioInManager::~IAudioInManager() = default;
+
+Result IAudioInManager::ListAudioIns(
+ OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_ins, Out<u32> out_count) {
+ LOG_DEBUG(Service_Audio, "called");
+ R_RETURN(this->ListAudioInsAutoFiltered(out_audio_ins, out_count));
+}
+
+Result IAudioInManager::OpenAudioIn(Out<AudioInParameterInternal> out_parameter_internal,
+ Out<SharedPointer<IAudioIn>> out_audio_in,
+ OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name,
+ InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name,
+ AudioInParameter parameter,
+ InCopyHandle<Kernel::KProcess> process_handle,
+ ClientAppletResourceUserId aruid) {
+ LOG_DEBUG(Service_Audio, "called");
+ R_RETURN(this->OpenAudioInProtocolSpecified(out_parameter_internal, out_audio_in, out_name,
+ name, {}, parameter, process_handle, aruid));
+}
+
+Result IAudioInManager::ListAudioInsAuto(
+ OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count) {
+ LOG_DEBUG(Service_Audio, "called");
+ R_RETURN(this->ListAudioInsAutoFiltered(out_audio_ins, out_count));
+}
+
+Result IAudioInManager::OpenAudioInAuto(
+ Out<AudioInParameterInternal> out_parameter_internal, Out<SharedPointer<IAudioIn>> out_audio_in,
+ OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
+ InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, AudioInParameter parameter,
+ InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid) {
+ LOG_DEBUG(Service_Audio, "called");
+ R_RETURN(this->OpenAudioInProtocolSpecified(out_parameter_internal, out_audio_in, out_name,
+ name, {}, parameter, process_handle, aruid));
+}
+
+Result IAudioInManager::ListAudioInsAutoFiltered(
+ OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count) {
+ LOG_DEBUG(Service_Audio, "called");
+ *out_count = impl->GetDeviceNames(out_audio_ins, true);
+ R_SUCCEED();
+}
+
+Result IAudioInManager::OpenAudioInProtocolSpecified(
+ Out<AudioInParameterInternal> out_parameter_internal, Out<SharedPointer<IAudioIn>> out_audio_in,
+ OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
+ InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, Protocol protocol,
+ AudioInParameter parameter, InCopyHandle<Kernel::KProcess> process_handle,
+ ClientAppletResourceUserId aruid) {
+ LOG_DEBUG(Service_Audio, "called");
+
+ if (!process_handle) {
+ LOG_ERROR(Service_Audio, "Failed to get process handle");
+ R_THROW(ResultUnknown);
+ }
+ if (name.empty() || out_name.empty()) {
+ LOG_ERROR(Service_Audio, "Invalid buffers");
+ R_THROW(ResultUnknown);
+ }
+
+ std::scoped_lock l{impl->mutex};
+
+ size_t new_session_id{};
+
+ R_TRY(impl->LinkToManager());
+ R_TRY(impl->AcquireSessionId(new_session_id));
+
+ LOG_DEBUG(Service_Audio, "Opening new AudioIn, session_id={}, free sessions={}", new_session_id,
+ impl->num_free_sessions);
+
+ const auto name_buffer = std::span(reinterpret_cast<const u8*>(name[0].name.data()), 0x100);
+ const auto device_name = Common::StringFromBuffer(name_buffer);
+ *out_audio_in = std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name,
+ parameter, process_handle.Get(), aruid.pid);
+ impl->sessions[new_session_id] = (*out_audio_in)->GetImpl();
+ impl->applet_resource_user_ids[new_session_id] = aruid.pid;
+
+ auto& out_system = impl->sessions[new_session_id]->GetSystem();
+ *out_parameter_internal =
+ AudioInParameterInternal{.sample_rate = out_system.GetSampleRate(),
+ .channel_count = out_system.GetChannelCount(),
+ .sample_format = static_cast<u32>(out_system.GetSampleFormat()),
+ .state = static_cast<u32>(out_system.GetState())};
+
+ out_name[0] = AudioDeviceName(out_system.GetName());
+
+ if (protocol == Protocol{}) {
+ if (out_system.IsUac()) {
+ out_name[0] = AudioDeviceName("UacIn");
+ } else {
+ out_name[0] = AudioDeviceName("DeviceIn");
+ }
+ }
+
+ R_SUCCEED();
+}
+
+} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio_in_manager.h b/src/core/hle/service/audio/audio_in_manager.h
new file mode 100644
index 000000000..2a983bc60
--- /dev/null
+++ b/src/core/hle/service/audio/audio_in_manager.h
@@ -0,0 +1,57 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "audio_core/audio_in_manager.h"
+#include "audio_core/in/audio_in_system.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::Audio {
+
+using AudioDeviceName = AudioCore::Renderer::AudioDevice::AudioDeviceName;
+using Protocol = std::array<u32, 2>;
+
+class IAudioIn;
+
+class IAudioInManager final : public ServiceFramework<IAudioInManager> {
+public:
+ explicit IAudioInManager(Core::System& system_);
+ ~IAudioInManager() override;
+
+private:
+ Result ListAudioIns(OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_audio_ins,
+ Out<u32> out_count);
+ Result OpenAudioIn(Out<AudioCore::AudioIn::AudioInParameterInternal> out_parameter_internal,
+ Out<SharedPointer<IAudioIn>> out_audio_in,
+ OutArray<AudioDeviceName, BufferAttr_HipcMapAlias> out_name,
+ InArray<AudioDeviceName, BufferAttr_HipcMapAlias> name,
+ AudioCore::AudioIn::AudioInParameter parameter,
+ InCopyHandle<Kernel::KProcess> process_handle,
+ ClientAppletResourceUserId aruid);
+
+ Result ListAudioInsAuto(OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins,
+ Out<u32> out_count);
+ Result OpenAudioInAuto(Out<AudioCore::AudioIn::AudioInParameterInternal> out_parameter_internal,
+ Out<SharedPointer<IAudioIn>> out_audio_in,
+ OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
+ InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name,
+ AudioCore::AudioIn::AudioInParameter parameter,
+ InCopyHandle<Kernel::KProcess> process_handle,
+ ClientAppletResourceUserId aruid);
+
+ Result ListAudioInsAutoFiltered(
+ OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_audio_ins, Out<u32> out_count);
+ Result OpenAudioInProtocolSpecified(
+ Out<AudioCore::AudioIn::AudioInParameterInternal> out_parameter_internal,
+ Out<SharedPointer<IAudioIn>> out_audio_in,
+ OutArray<AudioDeviceName, BufferAttr_HipcAutoSelect> out_name,
+ InArray<AudioDeviceName, BufferAttr_HipcAutoSelect> name, Protocol protocol,
+ AudioCore::AudioIn::AudioInParameter parameter,
+ InCopyHandle<Kernel::KProcess> process_handle, ClientAppletResourceUserId aruid);
+
+ std::unique_ptr<AudioCore::AudioIn::Manager> impl;
+};
+
+} // namespace Service::Audio